﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StructureMap;
using StructureMap.Pipeline;
using Library.Logging;
using Library.Structuremap;
using Core.Domain;
using Core.Dtos;
using Library.Cache;
using System.Runtime.Caching;
using Core.IServices;
using Core.Factories;
using Library.Helpers;
using AutoMapper;
using Core.Mappers;
using Services;
using Core.Aspects;
using StructureMap.Building.Interception;
using Core.Context;
using Share.Enterprise.DI;

namespace DI
{ 
    /// <summary>
    /// Bootstrapper class is used to initialize the application on start
    /// </summary>
    public static class Bootstrapper
    {
        public static Container Container
        {
            get
            {
                return DIContext.CurrentContainer;
            }
            set
            {
                DIContext.CurrentContainer = value;
            }
        }

        public static void Init(ILifecycle serviceLifecycle)
        {
            try
            {
                DIContext.CurrentContainer = new Container(x =>
                {
                    x.For<ILogger>().Singleton().Use<Log4NetAdapter>();

                    MemoryCache cache = new MemoryCache("app_cache");
                    x.For<ICacheStorage>().Singleton().Use<MemoryCacheStorage>().Ctor<MemoryCache>("cache").Is(cache);

                    x.AddRegistry(new RepositoryRegistry(serviceLifecycle));
                    x.AddRegistry(new ServiceRegistry(serviceLifecycle));
                    x.AddRegistry(new FactoryRegistry(serviceLifecycle));
                    x.AddRegistry(new AppContextRegistry(serviceLifecycle));
                    x.AddRegistry<GatewayRegistry>();                    
                });
                                           
                AutoMapperConfig.CreateMappings();                                
                Resolve<ILogger>().Log("App started");                
            }
            catch (Exception ex)
            {
                try
                {
                    Resolve<ILogger>().Log("App failed on start", ex);
                }catch(Exception){}
                throw;
            }
        }

        public static T Resolve<T>() where T : class
        {
            return (T)Container.TryGetInstance(typeof(T));
        }        
    }
}